﻿using System;
using System.Threading;
using OS.Common.Core;

namespace OS.Http.Extention
{
    /// <summary>
    /// 请求基类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BaseRestApi<T> : BaseRestApi<T, AppConfig> where T : class, new()
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="config">App配置信息</param>
        public BaseRestApi(AppConfig config = null)
            :base(config)
        {

        }
    }

    /// <summary>
    /// 通用App请求接口基类
    /// </summary>
    /// <typeparam name="T">动态实体</typeparam>
    /// <typeparam name="TConfigType">动态配置类型</typeparam>
    public class BaseRestApi<T, TConfigType> where T : class, new() where TConfigType : class, new()
    {
        private static readonly AsyncLocal<TConfigType> ContextConfig = new AsyncLocal<TConfigType>();

        private readonly TConfigType _confg;

        private static object _lockObj = new object();

        private static T _instance;

        /// <summary>
        /// 默认配置信息，如果实例中的配置为空会使用当前配置信息
        /// </summary>
        public static TConfigType DefaultConfig { get; set; }

        /// <summary>
        /// 接口配置
        /// </summary>
        public TConfigType ApiConfig
        {
            get
            {
                if (this._confg != null) return this._confg;
                if (ContextConfig.Value != null) return ContextConfig.Value;
                if (DefaultConfig != null) return DefaultConfig;
                throw new ArgumentNullException("当前配置信息为空，请通过SetContextConfig方法设置，或者构造函数中赋值，或者可以程序入口处给DefaultConifg赋值");
            }
        }

        /// <summary>
        /// 接口请求实例，当DefaultConfig设置之后，可以直接通过当前对象调用
        /// </summary>
        public static T Instance
        {
            get
            {
                if (_instance != null) return _instance;
                lock (_lockObj)
                {
                    if (_instance == null) _instance = new T();
                }

                return _instance;
            }
        }

        /// <summary>
        /// 模块名称
        /// </summary>
        protected static string ModuleName { get; set; } = "default";

        /// <summary>
        /// 设置上下文配置信息，当前配置在当前上下文中有效
        /// </summary>
        /// <param name="config"></param>
        public static void SetContextConfig(TConfigType config)
        {
            ContextConfig.Value = config;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="config">动态配置类型</param>
        public BaseRestApi(TConfigType config = null)
        {
            _confg = config;
        }
    }
}